#!/bin/bash

# This script will download and setup a cross compilation environment
# for targetting Win32 from Linux. It can also be used to build on
# Windows under the MSYS/MinGW environment.

if test $# -ne 1; then
  echo "usage: $0 vala_version" >&2;
  exit 1;
fi

DOWNLOAD_DIR="downloads"

VALA_DIR="`pwd`/vala-bin"
VALA_VERSION=$1; shift;
VALA_MAJOR_VERSION=`expr match $VALA_VERSION '\([0-9]*\.[0-9]*\)\..*'`;
VALA_URL="http://download.gnome.org/sources/vala"
VALA_SRC="$VALA_MAJOR_VERSION/vala-$VALA_VERSION.tar.bz2";

GTK_DIR="`pwd`/gtk-bin"
GTK_URL="http://ftp.gnome.org/pub/gnome/binaries/win32";
GTK_BINARIES=( \
  glib/2.26/glib{-dev,}_2.26.1-1_win32.zip \
  gtk+/2.22/gtk+{-dev,}_2.22.1-1_win32.zip \
  gdk-pixbuf/2.22/gdk-pixbuf{-dev,}_2.22.1-1_win32.zip \
  pango/1.26/pango{-dev,}_1.26.1-1_win32.zip \
  atk/1.32/atk{-dev,}_1.32.0-1_win32.zip
  dependencies/cairo{-dev,}_1.10.2-1_win32.zip \
  dependencies/gettext-{tools-dev,runtime,runtime-dev}_0.18.1.1-2_win32.zip \
  dependencies/fontconfig{-dev,}_2.8.0-2_win32.zip \
  dependencies/freetype{-dev,}_2.4.4-1_win32.zip \
  dependencies/expat_2.0.1-1_win32.zip \
  dependencies/libiconv-1.9.1.bin.woe32.zip \
  dependencies/libpng{-dev,}_1.4.3-1_win32.zip \
  dependencies/jpeg_8-1_win32.zip \
  dependencies/libtiff_3.9.2-1_win32.zip \
  dependencies/pkg-config_0.25-1_win32.zip\
  dependencies/zlib_1.2.5-2_win32.zip
);

MINGW_DIR="`pwd`/mingw-bin"
MINGW_URL="http://downloads.sourceforge.net/project/mingw/MinGW"
MINGW_BINARIES=(\
  BaseSystem/GNU-Binutils/binutils-2.21/binutils-2.21-2-mingw32-bin.tar.lzma
  BaseSystem/GCC/Version3/Current%20Release_%20gcc-3.4.5-20060117-3/gcc-core-3.4.5-20060117-3.tar.gz
  BaseSystem/RuntimeLibrary/MinGW-RT/mingwrt-3.18/mingwrt-3.18-mingw32-dev.tar.gz
  BaseSystem/RuntimeLibrary/MinGW-RT/mingwrt-3.18/mingwrt-3.18-mingw32-dll.tar.gz
);

function download_file ()
{
  local url="$1"; shift;
  local filename="$1"; shift;

  case "$DOWNLOAD_PROG" in
    curl)
      curl -C - -o "$DOWNLOAD_DIR/$filename" "$url";
    ;;
    *)
      $DOWNLOAD_PROG -O "$DOWNLOAD_DIR/$filename" -c "$url";
    ;;
  esac;

  if [ $? -ne 0 ]; then
    echo "Downloading ${url} failed.";
    exit 1;
  fi;
}

#function do_unzip ()
#{
#  local dir="$1"; shift;
#  local file="$1"; shift;
#
#  unzip -o -q -d "$dir" "$file" "$@";
#
#  if [ "$?" -ne 0 ]; then
#    echo "Failed to extract $file";
#    exit 1;
#  fi;
#}
#
#function do_lzma ()
#{
#  local dir="$1"; shift;
#  local file="$1"; shift;
#
#  cat $file | lzma -d -c | tar xv -C $dir
#
#  if [ "$?" -ne 0 ]; then
#    echo "Failed to extract $file";
#    exit 1;
#  fi;
#}
#
function uncomrpess ()
{
  local dir="$1"; shift;
  local file="$1"; shift;

  ext=${file##*\.}
  case "$ext" in
    zip)
      unzip -o -q -d "$dir" "$file" "$@";
    ;;
    lzma)
      cat $file | lzma -d -c | tar x -C $dir
    ;;
    gz)
      tar zxf $file -C $dir
    ;;
  esac;

  if [ "$?" -ne 0 ]; then
    echo "Failed to extract $file";
    exit 1;
  fi;
}

function find_compiler ()
{
  local gccbin fullpath;

  if [ -z "$MINGW_TOOL_PREFIX" ]; then
    for gccbin in i{3,4,5,6}86-mingw32{,msvc}-gcc; do
      fullpath="`which $gccbin 2>/dev/null`";
      if [ "$?" -eq 0 ]; then
        MINGW_TOOL_PREFIX="${fullpath%%gcc}";
        break;
      fi;
    done;
    if [ -z "$MINGW_TOOL_PREFIX" -a $MSYSTEM != "MINGW32" ]; then
      echo;
      echo "No suitable cross compiler was found.";
      echo;
      echo "If you already have a compiler installed,";
      echo "please set the MINGW_TOOL_PREFIX variable";
      echo "to point to its location without the";
      echo "gcc suffix (eg: \"/usr/bin/i386-mingw32-\").";
      echo;
      echo "If you are using Ubuntu, you can install a";
      echo "compiler by typing:";
      echo;
      echo " sudo apt-get install mingw32";
      echo;
      echo "Otherwise you can try following the instructions here:";
      echo;
      echo " http://www.libsdl.org/extras/win32/cross/README.txt";

      exit 1;
    fi;
  fi;

  export ADDR2LINE="${MINGW_TOOL_PREFIX}addr2line"
  export AS="${MINGW_TOOL_PREFIX}as"
  export CC="${MINGW_TOOL_PREFIX}gcc"
  export CPP="${MINGW_TOOL_PREFIX}cpp"
  export CPPFILT="${MINGW_TOOL_PREFIX}c++filt"
  export CXX="${MINGW_TOOL_PREFIX}g++"
  export DLLTOOL="${MINGW_TOOL_PREFIX}dlltool"
  export DLLWRAP="${MINGW_TOOL_PREFIX}dllwrap"
  export GCOV="${MINGW_TOOL_PREFIX}gcov"
  export LD="${MINGW_TOOL_PREFIX}ld"
  export NM="${MINGW_TOOL_PREFIX}nm"
  export OBJCOPY="${MINGW_TOOL_PREFIX}objcopy"
  export OBJDUMP="${MINGW_TOOL_PREFIX}objdump"
  export READELF="${MINGW_TOOL_PREFIX}readelf"
  export SIZE="${MINGW_TOOL_PREFIX}size"
  export STRINGS="${MINGW_TOOL_PREFIX}strings"
  export WINDRES="${MINGW_TOOL_PREFIX}windres"
  export AR="${MINGW_TOOL_PREFIX}ar"
  export RANLIB="${MINGW_TOOL_PREFIX}ranlib"
  export STRIP="${MINGW_TOOL_PREFIX}strip"
  export MAKENSIS="${MINGW_TOOL_PREFIX}makensis"

  echo -n "Using compiler $CC"

  TARGET="${MINGW_TOOL_PREFIX##*/}";
  TARGET="${TARGET%%-}";
  if [ -n $TARGET ]; then
    echo " and target $TARGET";
    TARGET="--host=$TARGET --target=$TARGET";
  else
    echo "";
    TARGET="";
  fi;
}

#Try to guess a download program if none has been specified
if [ -z "$DOWNLOAD_PROG" ]; then
  # If no download program has been specified then check if wget or
  # curl exists
  #wget first, because my curl can't download libsdl...
  for x in wget curl; do
    if [ "`type -t $x`" != "" ]; then
      DOWNLOAD_PROG="$x";
      break;
    fi;
  done;

  if [ -z "$DOWNLOAD_PROG" ]; then
    echo "No DOWNLOAD_PROG was set and neither wget nor curl is ";
    echo "available.";
    exit 1;
  fi;
fi;

###
## Download files
###

for bin in "${GTK_BINARIES[@]}"; do
  bn="${bin##*/}";
  download_file "$GTK_URL/$bin" "$bn"
done;

for bin in "${MINGW_BINARIES[@]}"; do
  bn="${bin##*/}";
  download_file "$MINGW_URL/$bin" "$bn"
done;

##
# Extract files
##

mkdir $GTK_DIR
for bin in "${GTK_BINARIES[@]}"; do
  echo "Extracting $bin...";
  bn="${bin##*/}";
  uncomrpess "$GTK_DIR" "$DOWNLOAD_DIR/$bn";
done;

mv "$GTK_DIR/README.libiconv" "$GTK_DIR/share/doc"

echo "Fixing pkgconfig files...";
for x in "$GTK_DIR/lib/pkgconfig/"*.pc; do
  sed "s/^prefix=.*\$/prefix=${quoted_root_dir}/" \
  < "$x" > "$x.tmp";
  mv "$x.tmp" "$x";
done;

mkdir $MINGW_DIR
for bin in "${MINGW_BINARIES[@]}"; do
  echo "Extracting $bin...";
  bn="${bin##*/}";
  uncomrpess "$MINGW_DIR" "$DOWNLOAD_DIR/$bn";
done;

vala_src="${VALA_SRC##*/}";
download_file "$VALA_URL/$VALA_SRC" "$vala_src";
tar jxf $DOWNLOAD_DIR/$vala_src
VALA_BUILD_DIR="vala-$VALA_VERSION"

##
# Build
##

export PKG_CONFIG_PATH="$GTK_DIR/lib/pkgconfig:$PKG_CONFIG_PATH";
export CPPFLAGS="-I$GTK_DIR/include -I$GTK_DIR/include/w32api $CPPFLAGS"
export LDFLAGS="-L$GTK_DIR/lib -mno-cygwin $LDFLAGS"
export CFLAGS="-I$GTK_DIR/include -mno-cygwin -mms-bitfields $CFLAGS"
if [ -n $TARGET ]; then
  export CFLAGS="$CFLAGS -march=i686"
fi;

find_compiler;

( cd "$VALA_BUILD_DIR" && ./configure --prefix="$GTK_DIR/../vala-bin" $TARGET );
if [ $? -ne 0 ]; then
  echo "configure failed";
  exit 1;
fi;

( cd "$VALA_BUILD_DIR" && make all install );
if [ $? -ne 0 ]; then
  echo "make failed";
  exit 1;
fi;

( cd "$VALA_DIR" && 7z a "../$VALA_BUILD_DIR.zip" );
if [ $? -ne 0 ]; then
  echo "zip failed";
fi;

$MAKENSIS \
    -DVALA_VERSION="$VALA_VERSION" -DVALA_MAJOR_VERSION=$VALA_MAJOR_VERSION \
    -DGTK_DIR="$GTK_DIR" -DMINGW_DIR="$MINGW_DIR" -DVALA_DIR="$VALADIR" \
    vala.nsi;
if [ $? -ne 0 ]; then
  echo "installer creation failed";
fi;

